package com.tg.app.activity.device.add;

import android.content.Context;
import android.content.Intent;
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.text.method.HideReturnsTransformationMethod;
import android.text.method.PasswordTransformationMethod;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.RequiresApi;

import com.demo.view.LoadingDialog;
import com.tange.module.core.wifi.scan.WiFiScanManager;
import com.tg.app.R;
import com.tg.app.helper.ActivityHelper;
import com.tg.appcommon.android.FontUtil;
import com.tg.appcommon.android.TGLog;
import com.tg.appcommon.android.TGToast;
import com.tg.appcommon.android.TGWifiUtil;

/**
 * 设置热点密码
 */
public class EnterPasswordActivity extends ApBaseActivity {

    public static final String PARAM_AP_SSID = "PARAM_AP_SSID";
    public static final String PARAM_WIFI_CAPABILITIES = "PARAM_WIFI_CAPABILITIES";

    private static final String TAG = "EnterPasswordActivityTAG";

    /**
     * Wifi连接超时时间
     */
    private static final int WIFI_CONNECTION_TIMEOUT = 10 * 1000;

    /**
     * Wifi连接广播过来不代表连好了，还需要握手等流程，因此延迟3s后再检测连接状态
     */
    private static final int WIFI_CONNECTION_DELAY_CHECK = 3 * 1000;

    /**
     * 最短密码位数
     */
    private static final int MIN_PWD_CHAR_COUNT = 8;

    private EditText edtPassword;
    private CheckBox pwdCheckBox;
    private Button btnNext;
    private View errorLayout;
    private TextView errorTv;
    private Button gotoSettingBtn;


    private String deviceWifiName;
    private String deviceWifiPwd;
    private String deviceWifiCapabilities;

    private LoadingDialog loadingDialog;

    private boolean alreadyGoToNextStep = false;

    private Handler timeOutHandler = new Handler(Looper.getMainLooper());
    private Handler uiHandler = new Handler(Looper.getMainLooper());

    public static void launch(Context context, String ssid, String capabilities) {
        Intent intent = new Intent(context, EnterPasswordActivity.class);
        intent.putExtra(PARAM_AP_SSID, ssid);
        intent.putExtra(PARAM_WIFI_CAPABILITIES, capabilities);
        context.startActivity(intent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_enter_ap_password);
        hideActionBar();
        initData();
        initView();
    }

    @Override
    public void onResume() {
        super.onResume();

        TGLog.i(TAG, "wifiConnected: call from page onResume()");
        wifiConnected();
    }

    private void initData() {
        deviceWifiName = getIntent().getStringExtra(PARAM_AP_SSID);
        deviceWifiCapabilities = getIntent().getStringExtra(PARAM_WIFI_CAPABILITIES);
    }

    private void setBtnEnabled(boolean enabled) {
        ActivityHelper.setLoginStyleButtonEnable(btnNext, enabled);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void initView() {
        errorLayout = findViewById(R.id.layout_error_tips);
        errorLayout.setVisibility(View.GONE);
        errorTv = findViewById(R.id.error_tv);
        gotoSettingBtn = findViewById(R.id.btn_go_to_wifi_setting);

        errorTv.setText(String.format(getString(R.string.connect_ap_wifi_by_yourself), deviceWifiName));
        gotoSettingBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
            }
        });

        RelativeLayout toolbar = findViewById(R.id.toolbar);
        TextView title = toolbar.findViewById(R.id.device_name);
        title.setText(R.string.ap_hotspot_password);
        modifyToolBar();
        loadingDialog = new LoadingDialog(this);
        loadingDialog.setCancelable(false);
        loadingDialog.setMsg(R.string.scan_qrcode_connecting);
        setClickBack(null);

        edtPassword = findViewById(R.id.edt_password);
        FontUtil.SetEditTextHintFontSize(edtPassword, 14);
        edtPassword.setTypeface(FontUtil.getMedium());
        pwdCheckBox = findViewById(R.id.checkBox);

        edtPassword.addTextChangedListener(new TextWatcher() {

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) { }

            @Override
            public void afterTextChanged(Editable s) {
                setBtnEnabled(s != null && s.length() > 0 && s.length() >= MIN_PWD_CHAR_COUNT);
            }
        });

        pwdCheckBox.setOnClickListener(v -> {
            if (pwdCheckBox.isChecked()) {
                edtPassword.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
            } else {
                edtPassword.setTransformationMethod(PasswordTransformationMethod.getInstance());
            }
            if (edtPassword.getText().toString().trim().length() > 0) {
                edtPassword.setSelection(edtPassword.getText().toString().trim().length());
            }
        });

        btnNext = findViewById(R.id.btn_old_next);
        btnNext.setOnClickListener(v -> connectWiFi());
        setBtnEnabled(false);

        pwdCheckBox.setChecked(true);
        edtPassword.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public void connectWiFi(){
        deviceWifiPwd = edtPassword.getText().toString().trim();

        if (TextUtils.isEmpty(deviceWifiPwd) || TextUtils.isEmpty(deviceWifiName) || TextUtils.isEmpty(deviceWifiCapabilities)) {
            return;
        }

        loadingDialog.show();
        timeOutHandler.removeCallbacksAndMessages(null);
        timeOutHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                TGLog.i(TAG, "connect timeout, show error tips");
                loadingDialog.dismiss();
                errorLayout.setVisibility(View.VISIBLE);
                TGToast.showToast(R.string.deivce_add_network_error);
            }
        }, WIFI_CONNECTION_TIMEOUT);

        TGWifiUtil.removeWifi(deviceWifiName, this);

        WiFiScanManager.scanner().addCameraWifiImpl(deviceWifiName, deviceWifiPwd, this, true, TGWifiUtil.getWifiCipher(deviceWifiCapabilities));
    }

    @Override
    public boolean shouldSetStatusBarColor() {
        return true;
    }

    @Override
    protected void wifiListChanged() {
        TGLog.i(TAG, "wifiListChanged");
    }

    @Override
    protected void wifiConnected() {

        WifiManager manager = (WifiManager)getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        if (manager == null) return;
        WifiInfo info = manager.getConnectionInfo();
        if (info == null) return;
        String wifi = info.getSSID().replace("\"","");
        if (wifi == null) return;

        TGLog.i(TAG, "wifiConnected: connected = " + wifi);
        TGLog.i(TAG, "wifiConnected: device target = " + deviceWifiName);

        if (wifi != null && wifi.equals(deviceWifiName)) {

            TGLog.i(TAG, "wifiConnected: WIFI connection state: " + info.getSupplicantState());

            // 当前WIFI不是COMPLETED，就延迟3s后再检查下，还不是COMPLETED就忽略本次回调。
            if (info.getSupplicantState() != SupplicantState.COMPLETED) {
                TGLog.i(TAG, "wifiConnected: WIFI connection state error: " + info.getSupplicantState());
                uiHandler.removeCallbacksAndMessages(null);
                uiHandler.postDelayed(new Runnable() {
                    @Override
                    public void run() {

                        WifiManager manager = (WifiManager)getApplicationContext().getSystemService(Context.WIFI_SERVICE);
                        if (manager == null) return;
                        WifiInfo info = manager.getConnectionInfo();
                        if (info == null) return;
                        String wifi = info.getSSID().replace("\"","");
                        TGLog.i(TAG, "wifiConnected: recheck: wifi = " + wifi);
                        if (wifi != null && wifi.equals(deviceWifiName)) {
                            TGLog.i(TAG, "wifiConnected: recheck: wifi.state = " + info.getSupplicantState());
                            if (info.getSupplicantState() == SupplicantState.COMPLETED) {
                                TGLog.i(TAG, "wifiConnected: recheck: complete after delay, so go to next step.");
                                launchNextStep();
                            } else {
                                TGLog.i(TAG, "wifiConnected: recheck: still not complete, ignore this time.");
                            }
                        }

                    }
                }, WIFI_CONNECTION_DELAY_CHECK);
            } else {
                TGLog.i(TAG, "wifiConnected: all complete, go to next step (ApSetWifiActivity).");
                launchNextStep();
            }
        } else {
            TGLog.i(TAG, "wifiConnected: not target wifi.");
        }
    }

    private void launchNextStep() {
        if (alreadyGoToNextStep) {
            TGLog.i(TAG, "wifiConnected: launch next activity BEFORE, so ignore.");
            return;
        }
        TGLog.i(TAG, "wifiConnected: launch next activity.");
        alreadyGoToNextStep = true;
        Intent intent = new Intent(getBaseContext(), ApSetWifiActivity.class);
        intent.putExtra(ApSetWifiActivity.EXT_UUID, deviceWifiName);
        intent.putExtra(ApSetWifiActivity.EXT_HOTSPOT_PWD, deviceWifiPwd);
        intent.putExtra(ApSetWifiActivity.EXT_HOTSPOT_CAPABILITIES, deviceWifiCapabilities);
        startActivity(intent);
        finish();
    }

    @Override
    protected void wifiUnavailable() {
        TGLog.i(TAG, "wifiUnavailable");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        timeOutHandler.removeCallbacksAndMessages(null);
        uiHandler.removeCallbacksAndMessages(null);
    }
}
